//## begin module%3C6E5F7403E6.cm preserve=no
//	  %X% %Q% %Z% %W%
//## end module%3C6E5F7403E6.cm

//## begin module%3C6E5F7403E6.cp preserve=no
//	+----------------------------------------------+
//	| SVMBR - A program for training SVMs          |
//	+----------------------------------------------+
//	| * Creator, modeling, coding:                 |
//	|    Marcelo Barros de Almeida                 |
//	|    barros@smar.com.br                        |
//	|    http://litc.cpdee.ufmg.br/~barros/        |
//	| * Coding, improvements, bug fixes:           |
//	|    Bernardo Penna                            |
//	|    bprc@brfree.com.br                        |
//	+----------------------------------------------+
//
//	 Copyright(c) 2002 by Marcelo Barros de Almeida
//	                            All rights reserved
//
//	-[CVS]------------------------------------------
//	$Author$
//	$Date$
//	$Source$
//	$Name$
//	$Revision$
//	------------------------------------------------
//## end module%3C6E5F7403E6.cp

//## Module: boostsolver%3C6E5F7403E6; Package body
//## Subsystem: <Top Level>
//## Source file: D:\textotese\svmbr\src\boostsolver.cpp

//## begin module%3C6E5F7403E6.additionalIncludes preserve=no
//## end module%3C6E5F7403E6.additionalIncludes

//## begin module%3C6E5F7403E6.includes preserve=yes
//## end module%3C6E5F7403E6.includes

// boostsolver
#include "boostsolver.h"
//## begin module%3C6E5F7403E6.declarations preserve=no
//## end module%3C6E5F7403E6.declarations

//## begin module%3C6E5F7403E6.additionalDeclarations preserve=yes
//## end module%3C6E5F7403E6.additionalDeclarations


// Class BoostingSolver 





BoostingSolver::BoostingSolver (REAL cv, REAL tolv, REAL epsilonv, SVM *svmp, Kernel *kernelp, Data *datap, INT chunksizev)
  //## begin BoostingSolver::BoostingSolver%1000989939.hasinit preserve=no
  //## end BoostingSolver::BoostingSolver%1000989939.hasinit
  //## begin BoostingSolver::BoostingSolver%1000989939.initialization preserve=yes
  //## end BoostingSolver::BoostingSolver%1000989939.initialization
{
  //## begin BoostingSolver::BoostingSolver%1000989939.body preserve=yes
	init(cv,tolv,epsilonv,svmp,kernelp,datap,chunksizev);
  //## end BoostingSolver::BoostingSolver%1000989939.body
}


BoostingSolver::~BoostingSolver()
{
  //## begin BoostingSolver::~BoostingSolver%.body preserve=yes
	freeSpace();
  //## end BoostingSolver::~BoostingSolver%.body
}



//## Other Operations (implementation)
INT BoostingSolver::run (INT maxi)
{
  //## begin BoostingSolver::run%1000989940.body preserve=yes
  INT i;
  numIter = 0;

  // initialize random seed
  SRAND(time(NULL));

  // start to count time
  crono.startCronometer();

  // main loop
	INT size = data->getnumExamples();
  INT numChanged = size;
	Z = size;

  cout << "Starting training (Boosting)." << endl << flush;

  while((numChanged > 0) /*&& (numIter < numIterMax)*/) {

    numChanged = 0;
		cout << "Boosting/ALL: " << flush;
    for(i = 0; i < size; i++){
			if(RAND(Z) <= D[i]){
				numChanged += examineExample(i);
				D[i]++;
				Z++;
			}
    }

		cout << "IT=" << ++numIter << " CH=" << numChanged << endl << flush;
		if(numChanged == 0) break;

  }

	//calcBias();
	bias = - bias;

  // finish time counting
  crono.stopCronometer();
	
  //calcNormW();
  return TRUE;

  //## end BoostingSolver::run%1000989940.body
}

INT BoostingSolver::run_chunck (INT maxi)
{
  //## begin BoostingSolver::run_chunck%1000989941.body preserve=yes
	cerr << "(BoostingSolver::run_chunck) Not implemented" << endl ;
	return FALSE;
  //## end BoostingSolver::run_chunck%1000989941.body
}

INT BoostingSolver::examineExample (UINT i)
{
  //## begin BoostingSolver::examineExample%1000989942.body preserve=yes
  REAL /*kernel,*/ dalpha, nalpha;
  INT j;
  INT  ret = 0;
  // calculate delta alpha
	INT target = data->gettarget(i);
  dalpha = target*errorCache[i]/(evalKernel(i,i) + 1);
  nalpha = alpha[i] - dalpha;
  // check bounds
  if(nalpha > (C-epsilon)) nalpha = C;
  if(nalpha < epsilon)     nalpha = 0;
  // dalpha after bounds
  dalpha   = alpha[i] - nalpha;
  alpha[i] = nalpha;

	
  if(ABS(dalpha)>tol){	
		REAL *row = cache->getKernelRow(i);
		for(j = 0  /*i + 1 */ ; j < data->getnumExamples(); j++){
			errorCache[j] = errorCache[j] - dalpha*target*(row[j]+1) ;
		}
    bias = bias - dalpha*target;
    ret = 1;
  }
  return ret;

  //## end BoostingSolver::examineExample%1000989942.body
}

INT BoostingSolver::run ()
{
  //## begin BoostingSolver::run%1000989943.body preserve=yes
	return run(-1);
  //## end BoostingSolver::run%1000989943.body
}

INT BoostingSolver::run_chunck ()
{
  //## begin BoostingSolver::run_chunck%1000989944.body preserve=yes
	return run_chunck(-1);
  //## end BoostingSolver::run_chunck%1000989944.body
}

VOID BoostingSolver::init (REAL cv, REAL tolv, REAL epsilonv, SVM *svmp, Kernel *kernelp, Data *datap, INT chunksizev)
{
  //## begin BoostingSolver::init%1000989945.body preserve=yes
	Solver::init(cv,tolv,epsilonv,svmp,kernelp,datap,chunksizev);

	try{
		D = new REAL [data->getnumExamples()];
	} 
	catch(...){
		cerr << "Error when allocating memory (BoostingSolver::init)." << endl;
		exit(1);
	}

	for(INT i = 0; i < data->getnumExamples(); i++){
		D[i] = 1;
	}

  //## end BoostingSolver::init%1000989945.body
}

VOID BoostingSolver::freeSpace ()
{
  //## begin BoostingSolver::freeSpace%1000989946.body preserve=yes
	Solver::freeSpace();
	delete D;
  //## end BoostingSolver::freeSpace%1000989946.body
}

// Additional Declarations
  //## begin BoostingSolver%3BA9E4050205.declarations preserve=yes
  //## end BoostingSolver%3BA9E4050205.declarations

//## begin module%3C6E5F7403E6.epilog preserve=yes
//## end module%3C6E5F7403E6.epilog
